package bl.controller;

import java.util.ArrayList;
import java.util.Iterator;

import po.MemberPO;
import po.UserIdentity;
import po.UserPO;

import database.factory.MemberDataFactory;
import database.factory.MemberDataFactoryImpl;
import database.factory.UserDataFactory;
import database.factory.UserDataFactoryImpl;
import database.service.MemberDataService;
import database.service.UserDataService;

import vo.UserVO;
import vo.BLToViewResultMessage;
import bl.domain.UserManagement;
import bl.service.UserManagementBLService;

public class UserManagementController implements UserManagementBLService {
	
	private UserManagement userManagement;
	
	public UserManagementController() {
		userManagement = new UserManagement();
	}

	private void init() {
		UserDataFactory userDataFactory = new UserDataFactoryImpl();
		UserDataService userDataService = userDataFactory.getUserDataService();
		userDataService.load();
		userManagement.setUserItr(userDataService.getIterator());
	}
	
	@Override
	public ArrayList<UserVO> getUserList() {
		init();
		ArrayList<UserVO> userVOs = new ArrayList<UserVO>();
		Iterator<UserPO> userItr = userManagement.getUserItr();
		while (userItr.hasNext()) {
			UserPO upo = userItr.next();
			if (upo.getId() > 0) {
				UserVO uvo = new UserVO(upo);
				userVOs.add(uvo);
 			}
		}
		return userVOs;
	}

	/**
	 * @return the success message of adding a user
	 * An administrator is not accessed to adding a member
	 * 
	 */
	@Override
	public BLToViewResultMessage addUser(UserVO user) {
		if (user == null) {
			return null;
		}
		
		init();
		UserPO newUser = user.getUserPO();
		
		UserDataFactory userDataFactory = new UserDataFactoryImpl();
		UserDataService userDataService = userDataFactory.getUserDataService();
		userDataService.load();
		int newUserID = userDataService.insert(newUser);
		userDataService.save();
		
		if (newUserID <= 0) {
			return null;
		}
		
		return BLToViewResultMessage.ADD_USER_SUCCESS;
	}

	/**
	 * When an administrator is deleting a member, the data of both member and user is changing
	 */
	@Override
	public BLToViewResultMessage deleteUser(int userID) {
		if (userID == 0) {
			return null;
		}		
		UserDataFactory userDataFactory = new UserDataFactoryImpl();
		UserDataService userDataService = userDataFactory.getUserDataService();
		userDataService.load();
		UserPO userPO = userDataService.find(userID);
		if (userPO == null) {
			return null;   
		}
		userDataService.delete(userPO);
		userDataService.save();
		
		if (userPO.getIdentity() == UserIdentity.CUSTOMER) {
			MemberDataFactory memberDataFactory = new MemberDataFactoryImpl();
			MemberDataService memberDataService = memberDataFactory.getMemberDataService();
			memberDataService.load();
			MemberPO member = memberDataService.find(userID);
			if (member == null) {
				return null;
			}
			memberDataService.delete(member);
			memberDataService.save();
		}
		
		return BLToViewResultMessage.DELETE_USER_SUCCESS;
	}

	@Override
	public BLToViewResultMessage modifyUser(int userID, UserVO user) {
		if (userID == 0) {
			return null;
		}
		
		init();
		UserPO newUser = user.getUserPO();
		
		UserDataFactory userDataFactory = new UserDataFactoryImpl();
		UserDataService userDataService = userDataFactory.getUserDataService();
		userDataService.load();
		UserPO userPO = userDataService.find(userID);
		if (userPO == null) {
			return null;
		}
		newUser.setId(userPO.getId());
		userDataService.update(userPO);
		userDataService.save();
		
		return BLToViewResultMessage.MODIFY_USER_SUCCESS;
	}

}
